package com.sjy.project.fym.api;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.sjy.common.constant.UserContext;
import com.sjy.common.entity.SecuryUserDetail;
import com.sjy.common.result.BaseResponse;
import com.sjy.common.utils.StringUtils;
import com.sjy.common.utils.TokenUtil;
import com.sjy.common.utils.WeChatUtils;
import com.sjy.framework.aspectj.lang.annotation.Log;
import com.sjy.framework.aspectj.lang.enums.BusinessType;
import com.sjy.framework.web.controller.BaseController;
import com.sjy.framework.web.page.TableDataInfo;
import com.sjy.project.fym.accessToken.domain.FyAccessToken;
import com.sjy.project.fym.accessToken.service.IFyAccessTokenService;
import com.sjy.project.fym.place.domain.FyPlace;
import com.sjy.project.fym.team.domain.FyTeam;
import com.sjy.project.fym.team.service.IFyTeamService;
import com.sjy.project.fym.user.domain.FyUser;
import com.sjy.project.fym.user.service.IFyUserService;
import com.sjy.project.system.user.domain.User;
import com.sjy.project.system.user.service.IUserService;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@Api(value = "经开区防疫用户信息", description = "用户信息相关接口", tags = {"经开区防疫"})
@RequestMapping({"/api/fym/user"})
public class ApiFyUserController extends BaseController {
  @Autowired
  private IFyUserService fyUserService;
  @Autowired
  private IFyTeamService fyTeamService;
  @Autowired
  private IFyAccessTokenService fyAccessTokenService;
  @Autowired
  private IUserService userService;
  
  @Autowired
  private TokenUtil tokenUtil;
  
  @ApiOperation(value = "901、根据openId判断当前用户是否已经绑定 绑定会返回token", position = 901, notes = "查重，如果已经绑定;;直接执行登录，并返回token")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "openId", value = "微信openId", required = false, example = "abcdef")
  })
  @PostMapping({"/noToken/isUserExist"})
  public ResponseEntity<BaseResponse<FyUser>> isUserExist(@ApiIgnore FyUser fyUser) {
    if (StringUtils.isEmpty(fyUser.getOpenId()) ) {
    	return BaseResponse.generateBadResponseEntity(500, "openId 不能为空", fyUser); 
    }
    
    FyUser user = fyUserService.selectFyUser("",fyUser.getOpenId());
    if (user == null) {
        return BaseResponse.generateBadResponseEntity(400, "未绑定用户!", user);
    } 
    String token = this.tokenUtil.generateToken(user.getPhonenumber(), user.getUserType(), user.getUserId(), user.getOpenId(),user.getUserName(),null);
    user.setToken(token);
    return BaseResponse.generateOKResponseEntity(user);
  }
  
  
  @ApiOperation(value = "902、如果用户没有绑定，直接根据openId生成临时token", position = 902, notes = "在901无效的情况下才回用到这个接口")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "openId", value = "微信openId", required = false, example = "abcdef")
  })
  @PostMapping({"/noToken/createTempToken"})
  public ResponseEntity<BaseResponse<String>> createTempToken(String openId) {
    String token = this.tokenUtil.generateToken(null, "1",null, openId,null,null);             
    return BaseResponse.generateOKResponseEntity(token);
  }
  
  @ApiOperation(value = "903、新增用户绑定", position = 903, notes = "绑定微信小程序、会查重;;;一个手机号只能同时绑定一个微信")
  @Log(title = "用户绑定", businessType = BusinessType.INSERT)
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "phonenumber", value = "手机号", required = false, example = "15858558918"), 
	  @ApiImplicitParam(name = "wechatCode", value = "微信code", required = false, example = "abcdef") , 
	  @ApiImplicitParam(name = "userName", value = "姓名", required = false, example = "xxx") 
  })
  @PostMapping({"/noToken/add"})
  public ResponseEntity<BaseResponse<FyUser>> add(String phonenumber,String wechatCode,String userName) {
    if (StringUtils.isEmpty(phonenumber)) {
        return BaseResponse.generateBadResponseEntity(500, "绑定必须要有手机号", phonenumber); 
    }
    String openId = WeChatUtils.getOpenid(wechatCode);
    if (StringUtils.isEmpty(openId)) {
    	return BaseResponse.generateBadResponseEntity(500, "code无效", wechatCode); 
    }
    FyUser user = this.fyUserService.selectFyUser(phonenumber, null);
    if (user != null) {
    	if(!user.getUserName().equals(userName)) {
    		return BaseResponse.generateBadResponseEntity(500, "信息有误无法绑定",phonenumber+";"+userName);
    	}
    	if (StringUtils.isNotEmpty(openId) && StringUtils.isEmpty(user.getOpenId())) {
    		user.setOpenId(openId);
    		user.setFirstBindingTime(new Date());
    		this.fyUserService.updateFyUser(user);
    		String str = this.tokenUtil.generateToken(user.getPhonenumber(), user.getUserType(), user.getUserId(), user.getOpenId(), user.getUserName(),null);
    		user.setToken(str);
    		return BaseResponse.generateOKResponseEntity("绑定微信成功", user);
    	} 
    	return BaseResponse.generateBadResponseEntity(500, "当前号码已经绑定", user);
    }else {
    	return BaseResponse.generateBadResponseEntity(500, "当前号码非工作人员无法绑定", phonenumber);
    }
  }
  
  @ApiOperation(value = "904、更新用户信息", position = 904, notes = "更新微信包括头像啥啥的")
  @PostMapping({"/noToken/edit"})
  public ResponseEntity<BaseResponse<FyUser>> edit(FyUser fyUser, HttpServletRequest request) {
    FyUser user = this.fyUserService.selectFyUserByUserId(fyUser.getUserId());
    if (user == null) {
        return BaseResponse.generateBadResponseEntity("用户信息无效", fyUser); 
    }
    if (!user.getPhonenumber().equals(fyUser.getPhonenumber()) || !user.getOpenId().equals(fyUser.getOpenId())) {
        return BaseResponse.generateBadResponseEntity("手机号或openId信息有误", fyUser); 
    }
    fyUser.setLoginDate(new Date());
    fyUser.setLoginIp(request.getLocalAddr());
    this.fyUserService.updateFyUser(fyUser);
    return BaseResponse.generateOKResponseEntity(fyUser);
  }
  
  @ApiOperation(value = "905、根据微信code获取用户信息", position = 905, notes = "后台先获取openId再获取accessToken  最后获取用户信息")
  @PostMapping({"/noToken/getWechatUserInfoByCode"})
  public ResponseEntity<BaseResponse<Object>> getWechatUserInfoByCode(@RequestParam(required = true) String wechatCode) {
	String openId = WeChatUtils.getOpenid(wechatCode);
	if(StringUtils.isNull(openId)) {
		 return BaseResponse.generateBadResponseEntity(500, "获取openId失败!",null);
	}
	FyUser user = fyUserService.selectFyUser("",openId);
	if (user == null) {
	    return BaseResponse.generateBadResponseEntity(400, "未绑定用户!", openId);
	} 
	String token = this.tokenUtil.generateToken(user.getPhonenumber(), user.getUserType(), user.getUserId(), user.getOpenId(),user.getUserName(),null);
	user.setToken(token);
	return BaseResponse.generateOKResponseEntity(user);
  }
  
  @ApiOperation(value = "906、获取accessToken", position = 906, notes = "经开区防疫的accesToken")
  @PostMapping({"/noToken/getAccessToken"})
  public ResponseEntity<BaseResponse<Object>> getXcxAccessToken() {
	  //获取最近一小时的token，如果获取不到，就重新请求并插入到accessToken表中
	  String accessToken = fyAccessTokenService.getAccessTokenNow()==null?"":fyAccessTokenService.getAccessTokenNow().getAccessToken();
	  if(StringUtils.isBlank(accessToken)) {
		  accessToken = WeChatUtils.getXcxAccessToken();
		  FyAccessToken fyAccessToken = new FyAccessToken();
		  fyAccessToken.setAccessToken(accessToken);
		  fyAccessToken.setCreateTime(new Date());
		  fyAccessTokenService.insertFyAccessToken(fyAccessToken);
	  }
	  return BaseResponse.generateOKResponseEntity(accessToken);
  }
  
  @ApiOperation(value = "907、获取用户信息", position = 907, notes = "获取用户微信基本信息（包括UnionID机制）")
  @PostMapping({"/noToken/getUserInfo"})
  public ResponseEntity<BaseResponse<Object>> getUserInfo(String openid,String accessToken) {
	  return BaseResponse.generateOKResponseEntity(WeChatUtils.getUserInfo(openid, accessToken));
  }
  
  @ApiOperation(value = "908、获取小程序码", position = 908, notes = "适用于需要的码数量较少的业务场景。通过该接口生成的小程序码，永久有效，有数量限制")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "placeId", value = "场所ID", required = true, example = "361"), 
	  @ApiImplicitParam(name = "path", value = "扫码进入的小程序页面路径，最大长度 128 字节，不能为空；对于小游戏，可以只传入 query 部分，来实现传参效果，如：传入 \"?foo=bar\"，即可在 wx.getLaunchOptionsSync 接口中的 query 参数获取到 {foo:\"bar\"}", required = true, example = "15858558918"), 
	  @ApiImplicitParam(name = "env_version", value = "要打开的小程序版本。正式版为 release，体验版为 trial，开发版为 develop", required = false, example = "release"), 
	  @ApiImplicitParam(name = "width", value = "二维码的宽度，单位 px。最小 280px，最大 1280px", required = false, example = "120") , 
	  @ApiImplicitParam(name = "auto_color", value = "自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调", required = false, example = "xxx") , 
	  @ApiImplicitParam(name = "line_color", value = "auto_color 为 false 时生效，使用 rgb 设置颜色 例如 {\"r\":\"xxx\",\"g\":\"xxx\",\"b\":\"xxx\"} 十进制表示", required = false, example = "xxx") , 
	  @ApiImplicitParam(name = "is_hyaline", value = "是否需要透明底色，为 true 时，生成透明底色的小程序码", required = false, example = "xxx")
  })
  @PostMapping(value = "/noToken/getwxacode",produces = MediaType.IMAGE_PNG_VALUE)
  
  public Object getwxacode(@RequestParam Long placeId,@RequestParam String path,@RequestParam(defaultValue = "release") String env_version
		  ,Integer width,boolean auto_color,Object line_color,boolean is_hyaline) {
	  String accessToken = fyAccessTokenService.getAccessTokenNow()==null?"":fyAccessTokenService.getAccessTokenNow().getAccessToken();
	  if(StringUtils.isBlank(accessToken)) {
		  accessToken = WeChatUtils.getXcxAccessToken();
		  FyAccessToken fyAccessToken = new FyAccessToken();
		  fyAccessToken.setAccessToken(accessToken);
		  fyAccessToken.setCreateTime(new Date());
		  fyAccessTokenService.insertFyAccessToken(fyAccessToken);
	  }
	  return WeChatUtils.getwxacode(placeId,accessToken,path, env_version,width,auto_color,line_color,is_hyaline).bodyBytes();
  }
  
  
  @ApiOperation(value = "908、获取小程序码", position = 908, notes = "适用于需要的码数量较少的业务场景。通过该接口生成的小程序码，永久有效，有数量限制")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "placeId", value = "场所ID", required = true, example = "361"), 
	  @ApiImplicitParam(name = "path", value = "扫码进入的小程序页面路径，最大长度 128 字节，不能为空；对于小游戏，可以只传入 query 部分，来实现传参效果，如：传入 \"?foo=bar\"，即可在 wx.getLaunchOptionsSync 接口中的 query 参数获取到 {foo:\"bar\"}", required = true, example = "15858558918"), 
  })
  @GetMapping(value = "/noToken/getwxacode2",produces = MediaType.IMAGE_PNG_VALUE)
  public Object getwxacode2(@RequestParam Long placeId,@RequestParam String path,HttpServletResponse response) {
	  String accessToken = fyAccessTokenService.getAccessTokenNow()==null?"":fyAccessTokenService.getAccessTokenNow().getAccessToken();
	  if(StringUtils.isBlank(accessToken)) {
		  accessToken = WeChatUtils.getXcxAccessToken();
		  FyAccessToken fyAccessToken = new FyAccessToken();
		  fyAccessToken.setAccessToken(accessToken);
		  fyAccessToken.setCreateTime(new Date());
		  fyAccessTokenService.insertFyAccessToken(fyAccessToken);
	  }
	  return WeChatUtils.getwxacode2(placeId,accessToken,path).bodyBytes();
  }
  
  @ApiOperation(value = "909、测试pgsql", position = 909, notes = "测试主从数据库的操作")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "userId", value = "用户编号", required = true, example = "101")
  })
  @PostMapping(value = "/noToken/testPgsql")
  public ResponseEntity<BaseResponse<TableDataInfo<FyUser>>> testPgsql(@ApiIgnore User user) {
	  startPage();
      List<User> list = userService.selectUserListPgsql(user);
      return BaseResponse.generateOKResponseEntity(getDataTable(list));
  }
  
  
  

  /**
   * 新增保存防疫人员信息
   */
  @ApiOperation(value = "601、新增防疫人员", position = 601, notes = "")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "teamId", value = "队伍编号", required = false, example = "200"),
	  @ApiImplicitParam(name = "userName", value = "姓名", required = false, example = "林"),
	  @ApiImplicitParam(name = "phonenumber", value = "手机号", required = false, example = "158"),
	  @ApiImplicitParam(name = "email", value = "邮箱", required = false, example = "158"),
	  @ApiImplicitParam(name = "idcard", value = "身份证", required = false, example = "158"),
	  @ApiImplicitParam(name = "sex", value = "用户性别 0=男,1=女,2=未知", required = false, example = "2"),
	  @ApiImplicitParam(name = "status", value = "帐号状态（0正常 1停用）", required = false, example = "0"),
	  @ApiImplicitParam(name = "leadOrg", value = "负责统筹单位", required = false, example = "林"),
	  @ApiImplicitParam(name = "fromOrg", value = "来源单位", required = false, example = "158"),
	  @ApiImplicitParam(name = "userType", value = "类别", required = false, example = "158"),
	  @ApiImplicitParam(name = "job", value = "岗位", required = false, example = "158"),
		 
	})
  @PostMapping("/add")
  public ResponseEntity<BaseResponse> addSave(@ApiIgnore FyUser fyUser)
  {
	if(StringUtils.isBlank(fyUser.getPhonenumber())||StringUtils.isBlank(fyUser.getUserName())) {
		return BaseResponse.generateBadResponseEntity("新增失败-号码跟姓名不能为空", null);
	}
  	//检测是否有重名队伍
  	FyUser exist = fyUserService.selectUserByPhonenumber(fyUser.getPhonenumber());
  	if(exist!=null) {
  		return BaseResponse.generateBadResponseEntity("新增失败-当前号码已存在", null);
  	}
  	//检测场所编号是否存在;;不存在提示报错，存在则更新场所名称
  	if(fyUser.getTeamId()!=null) {
  		FyTeam team = fyTeamService.selectFyTeamByTeamId(fyUser.getTeamId());
  		if(team == null) {
  			return BaseResponse.generateBadResponseEntity("队伍编号不存在!", fyUser.getTeamId());
  		}
  	  	SecuryUserDetail user = UserContext.getUserSession();
  	  	fyUser.setCreateBy(user.getLoginName());
  		fyUser.setTeamName(team.getTeamName());
  	}
  	
  	int flag = fyUserService.insertFyUser(fyUser);
  	if(flag>0) {
      	return BaseResponse.generateOKResponseEntity("新增成功"); 
  	}
  	return BaseResponse.generateBadResponseEntity("新增失败", fyUser);
  }
  
  /**
   * 删除防疫人员信息
   */
  @Log(title = "防疫人员信息", businessType = BusinessType.DELETE)
  @ApiOperation(value = "602、删除防疫人员信息", position = 602, notes = "英文半角逗号分割")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "ids", value = "id ,拼接字符串", required = false, example = "海城"),
		 
	 })
  @PostMapping( "/remove")
  public ResponseEntity<BaseResponse<String>> remove(String ids)
  {
  	int flag = fyUserService.deleteFyUserByUserIds(ids);
  	if(flag>0) {
      	return BaseResponse.generateOKResponseEntity("删除成功"); 
  	}
      return BaseResponse.generateBadResponseEntity("删除失败", ids);
  }
  
  /**
   * 修改保存防疫人员信息
   */
  @Log(title = "防疫人员信息", businessType = BusinessType.UPDATE)
  @PostMapping("/edit")
  @ApiOperation(value = "603、修改防疫人员信息", position = 603, notes = "")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "userId", value = "人员编号", required = true, example = "200"),
	  @ApiImplicitParam(name = "teamId", value = "队伍编号", required = false, example = "200"),
	  @ApiImplicitParam(name = "userName", value = "姓名", required = false, example = "林"),
	  @ApiImplicitParam(name = "phonenumber", value = "手机号", required = false, example = "158"),
	  @ApiImplicitParam(name = "email", value = "邮箱", required = false, example = "158"),
	  @ApiImplicitParam(name = "idcard", value = "身份证", required = false, example = "158"),
	  @ApiImplicitParam(name = "sex", value = "用户性别 0=男,1=女,2=未知", required = false, example = "2"),
	  @ApiImplicitParam(name = "status", value = "帐号状态（0正常 1停用）", required = false, example = "0"),
	  @ApiImplicitParam(name = "leadOrg", value = "负责统筹单位", required = false, example = "林"),
	  @ApiImplicitParam(name = "fromOrg", value = "来源单位", required = false, example = "158"),
	  @ApiImplicitParam(name = "userType", value = "类别", required = false, example = "158"),
	  @ApiImplicitParam(name = "job", value = "岗位", required = false, example = "158"),
		 
	 })
  public ResponseEntity<BaseResponse> editSave(@ApiIgnore FyUser fyUser)
  {
  	if(fyUser.getUserId()==null) {
      	return BaseResponse.generateBadResponseEntity("修改的时候userId不能为空", null);
  	}
  	SecuryUserDetail user = UserContext.getUserSession();
  	fyUser.setUpdateBy(user.getLoginName());
  	int flag = fyUserService.updateFyUser(fyUser);
  	if(flag>0) {
      	return BaseResponse.generateOKResponseEntity("修改成功"); 
  	}
      return BaseResponse.generateBadResponseEntity("修改失败", null);
  }

  
  @ApiOperation(value = "604、获取人员清单", position = 604, notes = "当前页:pageNum,分页大小：pageSize,排序字段：orderByColumn，排序方式：asc")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "teamName", value = "队伍名称", required = false, example = "200"),
	  @ApiImplicitParam(name = "userName", value = "姓名", required = false, example = "林"),
	  @ApiImplicitParam(name = "phonenumber", value = "手机号", required = false, example = "158"),
	  @ApiImplicitParam(name = "idcard", value = "身份证", required = false, example = "158"),
	  @ApiImplicitParam(name = "status", value = "帐号状态（0正常 1停用）", required = false, example = "0"),
	  @ApiImplicitParam(name = "leadOrg", value = "负责统筹单位", required = false, example = "林"),
	  @ApiImplicitParam(name = "fromOrg", value = "来源单位", required = false, example = "158"),
	  @ApiImplicitParam(name = "userType", value = "类别", required = false, example = "158"),
	  @ApiImplicitParam(name = "job", value = "岗位", required = false, example = "158"),
  })
  @PostMapping({"/list"})
  public ResponseEntity<BaseResponse<TableDataInfo<FyUser>>> list(@ApiIgnore FyUser fyUser)
  {
      startPage();
      List<FyUser> list = fyUserService.selectFyUserList(fyUser);
      return BaseResponse.generateOKResponseEntity(getDataTable(list));
  }
  
  @ApiOperation(value = "605、根据userId获取人员信息详情 包含队伍信息", position = 605, notes = "")
  @ApiImplicitParams({
	  @ApiImplicitParam(name = "userId", value = "人员编号", required = false, example = "1")
  })
  @PostMapping({"/getUserByUserId"})
  public ResponseEntity<BaseResponse<FyUser>> getUserByUserId(Long userId) throws Exception
  { 
  	FyUser fyUser = fyUserService.selectFyUserByUserId(userId);
  	if(fyUser != null) {
  		return BaseResponse.generateOKResponseEntity(fyUser);
  	}
  	return BaseResponse.generateBadResponseEntity(500,"获取队伍信息失败", null);
  	
  }
}
